package time

import (
	"strconv"
	"strings"
	"time"
)

var timeReplacer = strings.NewReplacer([]string{
	// year
	"Y", "2006", // A full numeric representation of a year, 4 digits Examples: 1999 or 2003
	"y", "06", //A two digit representation of a year Examples: 99 or 03

	// month
	"m", "01", // Numeric representation of a month, with leading zeros 01 through 12
	"n", "1", // Numeric representation of a month, without leading zeros 1 through 12
	"M", "Jan", // A short textual representation of a month, three letters Jan through Dec
	"F", "January", // A full textual representation of a month, such as January or March January through December

	// day
	"d", "02", // Day of the month, 2 digits with leading zeros 01 to 31
	"j", "2", // Day of the month without leading zeros 1 to 31

	// week
	"D", "Mon", // A textual representation of a day, three letters Mon through Sun
	"l", "Monday", // A full textual representation of the day of the week Sunday through Saturday

	// time
	"g", "3", // 12-hour format of an hour without leading zeros 1 through 12
	"G", "15", // 24-hour format of an hour without leading zeros 0 through 23
	"h", "03", // 12-hour format of an hour with leading zeros 01 through 12
	"H", "15", // 24-hour format of an hour with leading zeros 00 through 23

	"a", "pm", // Lowercase Ante meridiem and Post meridiem am or pm
	"A", "PM", // Uppercase Ante meridiem and Post meridiem AM or PM

	"i", "04", // Minutes with leading zeros 00 to 59
	"s", "05", // Seconds, with leading zeros 00 through 59
}...)

const (
	StdFormat = "Y-m-d H:i:s"
)

func FmtDate(t time.Time, format ...string) string {
	f := StdFormat
	if len(format) > 0 {
		f = strings.Join(format, "")
	}
	return t.Format(timeReplacer.Replace(f))
}

func FmtDuration(d time.Duration) string {
	d1 := time.Hour * 24
	d -= d % time.Second
	day := int(d / d1)
	if day > 0 {
		d = d % d1
		return strconv.Itoa(day) + "d" + d.String()
	}
	return d.String()
}

func ParseTimestamp(t string, format ...string) (int64, error) {
	f := StdFormat
	if len(format) > 0 {
		f = strings.Join(format, "")
	}
	tt, err := time.ParseInLocation(timeReplacer.Replace(f), t, time.Local)
	if err != nil {
		return 0, err
	}
	return tt.Unix(), nil
}

func ParseTime(t string, format ...string) (time.Time, error) {
	f := StdFormat
	if len(format) > 0 {
		f = strings.Join(format, "")
	}
	return time.ParseInLocation(timeReplacer.Replace(f), t, time.Local)
}
